home *** CD-ROM | disk | FTP | other *** search
/ Games of Daze / Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso / x2ftp / msdos / xlib / xlib06 / xvbitmap.asm < prev    next >
Assembly Source File  |  1993-09-12  |  22KB  |  681 lines

  1. ;-----------------------------------------------------------------------
  2. ; MODULE XVBITMAP
  3. ;
  4. ; Video Bitmap functions - Video Ram <-> Video Ram
  5. ;
  6. ; Compile with Tasm.
  7. ; C callable.
  8. ;
  9. ;
  10. ; ****** XLIB - Mode X graphics library                ****************
  11. ; ******                                               ****************
  12. ; ****** Written By Themie Gouthas                     ****************
  13. ;
  14. ; egg@dstos3.dsto.gov.au
  15. ; teg@bart.dsto.gov.au
  16. ;-----------------------------------------------------------------------
  17. COMMENT $
  18.  
  19. The XVBITMAP module implements yet another type of bitmap to complement
  20. planar and compiled bitmaps, VRAM based bitmaps. If a 4 cylinder car is
  21. analagous to planar bitmaps, that is thrifty on memory consumption but low
  22. performance and and a V8 is analagous to Compiled bitmaps, memory guzzlers
  23. that really fly, then VRAM based bitmaps are the 6 cylinder modest performers
  24. with acceptable memory consumption.
  25.  
  26. To summarise their selling points, VBM's are moderately fast with fair memory
  27. consumption, and unlike compiled bitmaps, can be clipped. The disadvantages
  28. are that they are limited by the amount of free video ram and have a complex
  29. structure.
  30.  
  31. The VRAM bitmap format is rather complex consisting of components stored in
  32. video ram and components in system ram working together. This complexity
  33. necessitates the existence of a creation function "x_make_vbm" which takes
  34. an input linear bitmap and generates the equivalent VBM (VRAM Bit Map).
  35.  
  36. VBM structure:
  37.  
  38.       WORD  0   Size          Total size of this VBM structure in bytes
  39.       WORD  1   ImageWidth    Width in bytes of the image (for all alignments)
  40.       WORD  2   ImageHeight   Height in scan lines of the image
  41.  
  42.       WORD  3 Alignment 0  ImagePtr   Offset in VidRAM of this aligned image
  43.    +--WORD  4              MaskPtr    Offset (within this structure's DS) of
  44.    |   .                   alignment masks
  45.    |   .
  46.    |   .
  47.    |  WORD  9 Alignment 3  ImagePtr   Offset in VidRAM of this aligned image
  48.   +|--WORD 10              MaskPtr    Offset (within this structure's DS) of
  49.   ||                              alignment masks
  50.   ||
  51.   |+->BYTE 21 (WORD 11)                -------+-- Image masks for alignment 0
  52.   |   .                                       |
  53.   |   .                                       |
  54.   |   BYTE  21 + ImageWidth*ImageHeight  -----+
  55.   |
  56.   |   .
  57.   |   . (similaly for alignments 1 - 2 )
  58.   |   .
  59.   |
  60.   +-->BYTE  21 + 3*ImageWidth*ImageHeight + 1-+-- Image masks for alignment 3
  61.       .                                       |
  62.       .                                       |
  63.       BYTE  21 + 4*(ImageWidth*ImageHeight) --+
  64.  
  65.       .
  66.       .
  67.       << Similarly for alignments 2 and 3 >>
  68.       .
  69.       .
  70.       BYTE 21 + 4*(ImageWidth*ImageHeight)
  71.   -------------
  72.  
  73.   (And dont forget the corresponding data in video ram)
  74.  
  75. $
  76.  
  77.  
  78. include xlib.inc
  79. include xvbitmap.inc
  80.  
  81. VBM_info_struc struc
  82.   Size        dw ?
  83.   ImageWidth  dw ?
  84.   ImageHeight dw ?
  85. ;  AlignData   dw ?
  86. VBM_info_struc ends
  87.  
  88. AlignData equ 6
  89.  
  90. VBM_alignment_struc struc
  91.   ImagePtr    dw ?
  92.   MaskPtr     dw ?
  93. VBM_alignment_struc ends
  94.  
  95.  
  96.     .code
  97.  
  98.  
  99. ;----------------------------------------------------------------------
  100. ; x_store_vbm_image
  101. ;
  102. ;  Store the linear bitmap in video RAM using the specified alignment and
  103. ;  start address. Returns number video ram bytes used.
  104. ;
  105. ;  THIS FUNCTION IS FOR USE BY x_make_masked_vbm
  106. ;
  107. ; Prototype:
  108. ;
  109. ;  x_store_vbm_image(unsigned int vramoffs, unsigned int Align,
  110. ;         char far *lbm);
  111. ;
  112. ;
  113. ; Written by Themie Gouthas
  114. ;----------------------------------------------------------------------
  115. _x_store_vbm_image  proc
  116.     ARG VramOffs:word,Align:word,LBitmap:dword
  117.     LOCAL BMWidth:byte=LocalStk
  118.     push  bp
  119.         mov   bp,sp
  120.     sub   sp,LocalStk                 ; Create space for local variables
  121.         push  si
  122.         push  di
  123.     push  ds
  124.     cld
  125.  
  126.     mov   ax,SCREEN_SEG               ; Point ES to screen segment
  127.     mov   es,ax
  128.     mov   di,[VramOffs]               ; Point ES:DI to VRAM dest start
  129.     mov   bx,[Align]                  ; Set BL to first pixel plane align
  130.         and   bl,03h
  131.  
  132.     lds   si,[LBitmap]                ; DS:SI -> source linear Bitmap
  133.         lodsw                             ; Al = B.M. width (bytes) AH = B.M.
  134.     mov   bh,ah                       ; Save source bitmap dimensions
  135.     mov   [BMWidth],al                ;
  136.  
  137.     mov   dx,SC_INDEX                 ; Initialize Map Mask for plane
  138.     mov   al,MAP_MASK                 ; selection
  139.         out   dx,al
  140.     inc   dx
  141.     xor   ch,ch                       ; clear CH
  142. @@RowLoop:
  143.     mov   cl,bl                       ; Set initial plane for current
  144.     mov   ah,11h                      ; allignment
  145.     shl   ah,cl
  146.  
  147.     mov   cl,[BMWidth]                ; Initialize column counter
  148. @@ColLoop:
  149.     mov   al,ah
  150.         out   dx,al                       ; set vga write plane
  151.     lodsb                             ; load next LBM pixel
  152.     mov   es:[di],al                  ; store it in Video Ram
  153.     shl   ah,1                        ; rotate plane mask
  154.     jnb   @@NoAddrIncr                ; Time to increment dest address ?
  155.     inc   di                          ; Yes: increment addr and reset
  156.     mov   ah,11h                      ;  plane mask to plane 0
  157. @@NoAddrIncr:
  158.     loop  @@ColLoop                   ; Loop to next pixel column
  159.     cmp   ah,11h
  160. ;    je    @@skip
  161.     inc   di                ; Increment dest addr
  162. ;@@skip:
  163.     dec   bh                          ; Decrement row counter
  164.     jnz   @@RowLoop                   ; Jump if more rows to go
  165.     mov   ax,di                       ; calculate video RAM consumed and
  166.     sub   ax,[VramOffs]               ;   return value
  167.  
  168.         pop   ds                          ; restore data segment
  169.     pop   di                          ; restore registers
  170.         pop   si
  171.         mov   sp,bp                       ; dealloc local variables
  172.     pop   bp
  173.         ret
  174. _x_store_vbm_image  endp
  175.  
  176.  
  177. _x_put_masked_vbm  proc
  178.     ARG X:word,Y:word,ScrnOffs:word,SrcVBM:dword
  179.     LOCAL VBMWidth:word,VBMHeight:word,NextLineIncr:word=LocalStk
  180.     push  bp
  181.         mov   bp,sp
  182.     sub   sp,LocalStk                 ; Create space for local variables
  183.         push  si
  184.         push  di
  185.     push  ds
  186.     cld
  187.  
  188.     mov   ax,SCREEN_SEG               ; Point es to VGA segment
  189.         mov   es,ax
  190.         mov   ax,[Y]                      ; Calculate dest screen row
  191.     mov   cx,[_ScrnLogicalByteWidth]  ;  by mult. dest Y coord by Screen
  192.     mul   cx                          ;  width then adding screen offset
  193.  
  194.     mov   di,[ScrnOffs]               ;  store result in DI
  195.         add   di,ax
  196.     mov   si,[X]                      ; Load X coord into CX and make a
  197.     mov   bx,si                       ;  copy in DX
  198.     shr   bx,2                        ; Find starting byte in dest row
  199.     add   di,bx                       ;  add to DI giving screen offset of
  200.                                           ;  first pixel's byte
  201.  
  202.     and   si,3                        ; get pixel alignment in si
  203.  
  204.     lds   bx,[SrcVBM]                 ; DS:BX -> VBM data structure
  205.     shl   si,2                        ; si = offset of data  for curr
  206.                       ; alignment
  207.  
  208.     mov ax,word ptr [bx+ImageHeight]  ; Get image height
  209.     mov   [VBMHeight],ax
  210.     mov ax,word ptr [bx+ImageWidth]   ; Get image width
  211.     mov   [VBMWidth],ax
  212.  
  213.     sub   cx,ax                       ; NextLineIncr = bytes to the begin.
  214.     mov   [NextLineIncr],cx           ;  of bitmaps next row on screen
  215.     mov   dx,[bx+MaskPtr+AlignData+si]  ; DS:SI -> mask data
  216.     mov   bx,[bx+ImagePtr+AlignData+si] ; ES:BX -> source video bitmap
  217.     mov   si,dx
  218.  
  219.     mov   dx,GC_INDEX                 ; Set bit mask for all bits from
  220.     mov   ax,BIT_MASK                 ; VGA latches and none from CPU
  221.     out   dx,ax
  222.  
  223.     mov   dx,SC_INDEX                 ; Point SC register to map mask
  224.     mov   al,MAP_MASK                 ; in preperation for masking data
  225.     out   dx,al
  226.     inc   dx                          ; Point dx to SC data register
  227.     mov   ah,byte ptr [VBMHeight]     ; AH = Scanline loop counter
  228.  
  229. @@RowLoop:
  230.     mov   cx,[VBMWidth]               ; Width in bytes across
  231.  
  232. @@ColumnLoop:
  233.     lodsb
  234.     out   dx,al
  235.     mov   al,es:[bx]                  ; load latches from source bitmap
  236.     stosb                             ; store latches to dest. bitmap
  237.     inc   bx
  238.     loop  @@ColumnLoop
  239.  
  240.     add   di,[NextLineIncr]           ; point to start of next dest row
  241.     dec   ah                          ; decrement scan line counter
  242.     jnz   @@RowLoop                   ; jump if more scanlines left
  243.  
  244.     mov   dx,GC_INDEX+1               ; Restore bitmask to the default -
  245.     mov   al,0ffh                     ;  all data from cpu
  246.     out   dx,al
  247.  
  248.         pop   ds                          ; restore data segment
  249.         pop   di                          ; restore registers
  250.         pop   si
  251.         mov   sp,bp                       ; dealloc local variables
  252.         pop   bp
  253.         ret
  254. _x_put_masked_vbm  endp
  255.  
  256.  
  257. _x_put_masked_vbm_clipx  proc
  258. ARG X:word,Y:word,ScrnOffs:word,SrcVBM:dword
  259. LOCAL DataInc,LeftSkip,VBMWidth,VBMHeight,NextLineIncr:word=LocalStk
  260.     push  bp
  261.         mov   bp,sp
  262.     sub   sp,LocalStk             ; Create space for local variables
  263.         push  si
  264.         push  di
  265.     push  ds
  266.     cld
  267.  
  268.     mov   di,[X]                  ; load X coord int DI and make a
  269.     mov   si,di                   ;  copy in SI
  270.     sar   di,2                    ; Find Byte offset of X coord
  271.  
  272.     and   si,3                    ; Calculate pixels plane alignment
  273.     shl   si,2                    ; Prepare to lookup mask & data
  274.     les   bx,[SrcVBM]             ; ES:BX -> begining of VBM data
  275.  
  276.     mov   cx,es:[bx+ImageWidth]   ; Get image width and save in CX
  277.  
  278.  
  279.  
  280.     ;;;;; CLIP PROCESSING FOR LEFT CLIP BORDER ;;;;;;;;;;;;;;;;;;;
  281.  
  282.     mov   dx,[_LeftClip]
  283.     sub   dx,di
  284.     jle   @@NotLeftClip
  285.     cmp   dx,cx
  286.     jnl   @@NotVisible
  287.     add   di,dx
  288.     mov   [LeftSkip],dx
  289.     mov   [DataInc],dx
  290.     sub   cx,dx
  291.     jmp   short @@HorizClipDone
  292.  
  293.         ;;;; EXIT FOR COMPLETELY OBSCURED V.B.M's ;;;;;;;;;;;;;;;;;;;;;;
  294.  
  295. @@NotVisible:
  296.     mov   ax,1
  297.     pop   ds                          ; restore data segment
  298.     pop   di                          ; restore registers
  299.     pop   si
  300.     mov   sp,bp                       ; dealloc local variables
  301.     pop   bp
  302.     ret
  303.  
  304.     ;;;;; CLIP PROCESSING FOR RIGHT CLIP BORDER ;;;;;;;;;;;;;;;;;;;
  305.  
  306. @@NotLeftClip:
  307.     mov   dx,[_RightClip]
  308.     sub   dx,di
  309.     js    @@NotVisible
  310.     mov   [LeftSkip],0
  311.     mov   [DataInc],0
  312.     cmp   dx,cx
  313.     jge   @@HorizClipDone
  314.     inc   dx
  315.     sub   cx,dx
  316.     mov   [DataInc],cx
  317.     mov   cx,dx
  318.  
  319. @@HorizClipDone:
  320.  
  321.  
  322.     add   di,[ScrnOffs]           ; Add the current page offset
  323.     mov   [VBMWidth],cx
  324.     mov   ax,es:[bx+ImageHeight]  ; Get image height and save in AX
  325.     mov   [VBMHeight],ax
  326.  
  327.  
  328.     ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  329.  
  330.     mov   ax,[Y]                      ; Calculate dest screen row
  331.     mov   cx,[_ScrnLogicalByteWidth]  ;  by mult. dest Y coord by Screen
  332.     mul   cx                          ;  width then adding screen offset
  333.     add   di,ax                       ; Add Dest Screen Row to di
  334.     sub   cx,[VBMWidth]
  335.     mov   [NextLineIncr],cx
  336.  
  337.     mov   ax,es                       ; copy ES to DS
  338.     mov   ds,ax
  339.     mov   ax,SCREEN_SEG               ; Point es to VGA segment
  340.     mov   es,ax
  341.  
  342.     mov   ax,[bx+MaskPtr+AlignData+si]  ; DS:SI -> mask data
  343.     mov   bx,[bx+ImagePtr+AlignData+si] ; ES:BX -> source video bitmap
  344.     mov   si,ax
  345.  
  346.     mov   ax,[LeftSkip]               ; Skip data/mask bytes in
  347.     add   bx,ax                       ; each row that have been clipped
  348.     add   si,ax                       ; by the L.H.S border
  349.  
  350.  
  351.     mov   dx,GC_INDEX                 ; Set bit mask for all bits from
  352.     mov   ax,BIT_MASK                 ; VGA latches and none from CPU
  353.     out   dx,ax
  354.     mov   dx,SC_INDEX                 ; Point SC register to map mask
  355.     mov   al,MAP_MASK                 ; in preperation for masking data
  356.     out   dx,al
  357.     inc   dx                          ; Point dx to SC data register
  358.     mov   ah,byte ptr [VBMHeight]     ; AH = Scanline loop counter
  359.  
  360. @@RowLoop:
  361.     mov   cx,[VBMWidth]               ; Width in bytes across
  362.  
  363. @@ColumnLoop:
  364.     lodsb
  365.     out   dx,al
  366.     mov   al,es:[bx]                  ; load latches from source bitmap
  367.     stosb                             ; store latches to dest. bitmap
  368.     inc   bx
  369.     loop  @@ColumnLoop
  370.     add   bx,[DataInc]
  371.     add   si,[DataInc]
  372.     add   di,[NextLineIncr]           ; point to start of next dest row
  373.     dec   byte ptr ah                 ; decrement scan line counter
  374.     jnz   @@RowLoop                   ; jump if more scanlines left
  375.  
  376.     mov   dx,GC_INDEX+1               ; Restore bitmask to the default -
  377.     mov   al,0ffh                     ;  all data from cpu
  378.     out   dx,al
  379.     xor   ax,ax
  380.     pop   ds                          ; restore data segment
  381.     pop   di                          ; restore registers
  382.     pop   si
  383.     mov   sp,bp                       ; dealloc local variables
  384.     pop   bp
  385.     ret
  386. _x_put_masked_vbm_clipx  endp
  387.  
  388.  
  389. _x_put_masked_vbm_clipy  proc
  390. ARG X:word,Y:word,ScrnOffs:word,SrcVBM:dword
  391. LOCAL VBMWidth,VBMHeight,TopRow,NextLineIncr:word=LocalStk
  392.     push  bp
  393.     mov   bp,sp
  394.     sub   sp,LocalStk                 ; Create space for local variables
  395.     push  si
  396.     push  di
  397.     push  ds
  398.     cld
  399.  
  400.     mov   di,[X]                  ; load X coord int DI and make a
  401.     mov   si,di                   ;  copy in SI
  402.  
  403.  
  404.     and   si,3                    ; Calculate pixels plane alignment
  405.     shl   si,2                    ; Prepare to lookup mask & data
  406.     les   bx,[SrcVBM]             ; ES:BX -> begining of VBM data
  407.  
  408.  
  409.     mov   ax,es:[bx+ImageHeight]  ; Get image height and save in AX
  410.  
  411.  
  412.  
  413.     ;;;;; CLIP PROCESSING FOR TOP CLIP BORDER ;;;;;;;;;;;;;;;;;;;;;
  414.  
  415.     mov   dx,[_TopClip]           ; Compare u.l. Y coord with Top
  416.     sub   dx,[Y]                  ; clipping border
  417.     jle   @@NotTopClip            ; jump if VBM not clipped from above
  418.     cmp   dx,ax
  419.     jnl   @@NotVisible            ; jump if VBM is completely obscured
  420.     mov   [TopRow],dx
  421.     sub   ax,dx
  422.     add   [Y],dx
  423.     jmp   short @@VertClipDone
  424.  
  425.     ;;;; EXIT FOR COMPLETELY OBSCURED V.B.M's ;;;;;;;;;;;;;;;;;;;;;;
  426.  
  427. @@NotVisible:
  428.     mov   ax,1
  429.     pop   ds                          ; restore data segment
  430.     pop   di                          ; restore registers
  431.     pop   si
  432.     mov   sp,bp                       ; dealloc local variables
  433.     pop   bp
  434.     ret
  435.  
  436.     ;;;;; CLIP PROCESSING FOR BOTTOM CLIP BORDER ;;;;;;;;;;;;;;;;;;;
  437.  
  438. @@NotTopClip:
  439.     mov   dx,[_BottomClip]
  440.     sub   dx,[Y]
  441.     js    @@NotVisible
  442.     mov   [TopRow],0
  443.     cmp   dx,ax
  444.     jg    @@VertClipDone
  445.     inc   dx
  446.     mov   ax,dx
  447.  
  448. @@VertClipDone:
  449.  
  450.  
  451.     shr   di,2                    ; Find Byte offset of X coord
  452.     add   di,[ScrnOffs]           ; Add the current page offset
  453.     mov   cx,es:[bx+ImageWidth]   ; Get image width and save in CX
  454.     mov   [VBMWidth],cx
  455.     mov   [VBMHeight],ax
  456.  
  457.     ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  458.  
  459.     mov   ax,[Y]                      ; Calculate dest screen row
  460.     mov   cx,[_ScrnLogicalByteWidth]  ;  by mult. dest Y coord by Screen
  461.     mul   cx                          ;  width then adding screen offset
  462.     add   di,ax                       ; Add Dest Screen Row to di
  463.     sub   cx,[VBMWidth]
  464.     mov   [NextLineIncr],cx
  465.  
  466.     mov   ax,es                       ; copy ES to DS
  467.     mov   ds,ax
  468.     mov   ax,SCREEN_SEG               ; Point es to VGA segment
  469.     mov   es,ax
  470.  
  471.     mov   ax,[bx+MaskPtr+AlignData+si]  ; DS:SI -> mask data
  472.     mov   bx,[bx+ImagePtr+AlignData+si] ; ES:BX -> source video bitmap
  473.     mov   si,ax
  474.  
  475.  
  476.  
  477.     mov   ax,[VBMWidth]               ; Increment DS:BX and DS:SI to
  478.     mul   [TopRow]                    ;  skip image/mask data that has
  479.     add   bx,ax                       ;  been clipped by the top border
  480.     add   si,ax
  481.  
  482.  
  483.     mov   dx,GC_INDEX                 ; Set bit mask for all bits from
  484.     mov   ax,BIT_MASK                 ; VGA latches and none from CPU
  485.     out   dx,ax
  486.     mov   dx,SC_INDEX                 ; Point SC register to map mask
  487.     mov   al,MAP_MASK                 ; in preperation for masking data
  488.     out   dx,al
  489.     inc   dx                          ; Point dx to SC data register
  490.     mov   ah,byte ptr [VBMHeight]     ; AH = Scanline loop counter
  491.  
  492. @@RowLoop:
  493.     mov   cx,[VBMWidth]               ; Width in bytes across
  494.  
  495. @@ColumnLoop:
  496.     lodsb
  497.     out   dx,al
  498.     mov   al,es:[bx]                  ; load latches from source bitmap
  499.     stosb                             ; store latches to dest. bitmap
  500.     inc   bx
  501.     loop  @@ColumnLoop
  502.     add   di,[NextLineIncr]           ; point to start of next dest row
  503.     dec   byte ptr ah                 ; decrement scan line counter
  504.     jnz   @@RowLoop                   ; jump if more scanlines left
  505.  
  506.     mov   dx,GC_INDEX+1               ; Restore bitmask to the default -
  507.     mov   al,0ffh                     ;  all data from cpu
  508.     out   dx,al
  509.  
  510.     xor   ax,ax
  511.     pop   ds                          ; restore data segment
  512.     pop   di                          ; restore registers
  513.     pop   si
  514.     mov   sp,bp                       ; dealloc local variables
  515.     pop   bp
  516.     ret
  517. _x_put_masked_vbm_clipy  endp
  518.  
  519. _x_put_masked_vbm_clipxy  proc
  520. ARG X:word,Y:word,ScrnOffs:word,SrcVBM:dword
  521. LOCAL DataInc,LeftSkip,VBMWidth,VBMHeight,TopRow,NextLineIncr:word=LocalStk
  522.     push  bp
  523.     mov   bp,sp
  524.     sub   sp,LocalStk                 ; Create space for local variables
  525.     push  si
  526.     push  di
  527.     push  ds
  528.     cld
  529.  
  530.     mov   di,[X]                  ; load X coord int DI and make a
  531.     mov   si,di                   ;  copy in SI
  532.     sar   di,2                    ; Find Byte offset of X coord
  533.     and   si,3                    ; Calculate pixels plane alignment
  534.     shl   si,2                    ; Prepare to lookup mask & data
  535.     les   bx,[SrcVBM]             ; ES:BX -> begining of VBM data
  536.  
  537.     mov   cx,es:[bx+ImageWidth]   ; Get image width and save in CX
  538.     mov   ax,es:[bx+ImageHeight]  ; Get image height and save in AX
  539.  
  540.  
  541.  
  542.     ;;;;; CLIP PROCESSING FOR TOP CLIP BORDER ;;;;;;;;;;;;;;;;;;;;;
  543.  
  544.     mov   dx,[_TopClip]           ; Compare u.l. Y coord with Top
  545.     sub   dx,[Y]                  ; clipping border
  546.     jle   @@NotTopClip            ; jump if VBM not clipped from above
  547.     cmp   dx,ax
  548.     jnl   @@NotVisible            ; jump if VBM is completely obscured
  549.     mov   [TopRow],dx
  550.     sub   ax,dx
  551.     add   [Y],dx
  552.     jmp   short @@VertClipDone
  553.  
  554.     ;;;; EXIT FOR COMPLETELY OBSCURED V.B.M's ;;;;;;;;;;;;;;;;;;;;;;
  555.  
  556. @@NotVisible:
  557.     mov   ax,1
  558.     pop   ds                          ; restore data segment
  559.     pop   di                          ; restore registers
  560.     pop   si
  561.     mov   sp,bp                       ; dealloc local variables
  562.     pop   bp
  563.     ret
  564.  
  565.     ;;;;; CLIP PROCESSING FOR BOTTOM CLIP BORDER ;;;;;;;;;;;;;;;;;;;
  566.  
  567. @@NotTopClip:
  568.     mov   dx,[_BottomClip]
  569.     sub   dx,[Y]
  570.     js    @@NotVisible
  571.     mov   [TopRow],0
  572.     cmp   dx,ax
  573.     jg    @@VertClipDone
  574.     inc   dx
  575.     mov   ax,dx
  576.  
  577. @@VertClipDone:
  578.  
  579.     ;;;;; CLIP PROCESSING FOR LEFT CLIP BORDER ;;;;;;;;;;;;;;;;;;;
  580.  
  581.  
  582.     mov   dx,[_LeftClip]
  583.     sub   dx,di
  584.     jle   @@NotLeftClip
  585.     cmp   dx,cx
  586.     jnl   @@NotVisible
  587.     add   di,dx
  588.     mov   [LeftSkip],dx
  589.     mov   [DataInc],dx
  590.     sub   cx,dx
  591.     jmp   short @@HorizClipDone
  592.  
  593.     ;;;;; CLIP PROCESSING FOR RIGHT CLIP BORDER ;;;;;;;;;;;;;;;;;;;
  594.  
  595. @@NotLeftClip:
  596.     mov   dx,[_RightClip]
  597.     sub   dx,di
  598.     js    @@NotVisible
  599.     mov   [LeftSkip],0
  600.     mov   [DataInc],0
  601.     cmp   dx,cx
  602.     jge    @@HorizClipDone
  603.     inc   dx
  604.     sub   cx,dx
  605.     mov   [DataInc],cx
  606.     mov   cx,dx
  607.  
  608. @@HorizClipDone:
  609.  
  610.     add   di,[ScrnOffs]           ; Add the current page offset
  611.     mov   [VBMWidth],cx
  612.     mov   [VBMHeight],ax
  613.     ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  614.  
  615.     mov   ax,[Y]                      ; Calculate dest screen row
  616.     mov   cx,[_ScrnLogicalByteWidth]  ;  by mult. dest Y coord by Screen
  617.     mul   cx                          ;  width then adding screen offset
  618.     add   di,ax                       ; Add Dest Screen Row to di
  619.     sub   cx,[VBMWidth]
  620.     mov   [NextLineIncr],cx
  621.  
  622.     mov   ax,es                       ; copy ES to DS
  623.     mov   ds,ax
  624.     mov   ax,SCREEN_SEG               ; Point es to VGA segment
  625.     mov   es,ax
  626.  
  627.     mov   ax,[bx+MaskPtr+AlignData+si]  ; DS:SI -> mask data
  628.     mov   bx,[bx+ImagePtr+AlignData+si] ; ES:BX -> source video bitmap
  629.     mov   si,ax
  630.  
  631.  
  632.  
  633.     mov   ax,[VBMWidth]               ; Increment DS:BX and DS:SI to
  634.     add   ax,[DataInc]                ;  skip image/mask data that has
  635.     mul   [TopRow]                    ;  been clipped by the top border
  636.     add   ax,[LeftSkip]               ; Skip also data/mask bytes in
  637.     add   bx,ax                       ; each row that have been clipped
  638.     add   si,ax                       ; by the L.H.S border
  639.  
  640.  
  641.     mov   dx,GC_INDEX                 ; Set bit mask for all bits from
  642.     mov   ax,BIT_MASK                 ; VGA latches and none from CPU
  643.     out   dx,ax
  644.     mov   dx,SC_INDEX                 ; Point SC register to map mask
  645.     mov   al,MAP_MASK                 ; in preperation for masking data
  646.     out   dx,al
  647.     inc   dx                          ; Point dx to SC data register
  648.     mov   ah,byte ptr [VBMHeight]     ; AH = Scanline loop counter
  649.  
  650. @@RowLoop:
  651.     mov   cx,[VBMWidth]               ; Width in bytes across
  652.  
  653. @@ColumnLoop:
  654.     lodsb
  655.     out   dx,al
  656.     mov   al,es:[bx]                  ; load latches from source bitmap
  657.     stosb                             ; store latches to dest. bitmap
  658.     inc   bx
  659.     loop  @@ColumnLoop
  660.     add   bx,[DataInc]
  661.     add   si,[DataInc]
  662.     add   di,[NextLineIncr]           ; point to start of next dest row
  663.     dec   byte ptr ah                 ; decrement scan line counter
  664.     jnz   @@RowLoop                   ; jump if more scanlines left
  665.  
  666.     mov   dx,GC_INDEX+1               ; Restore bitmask to the default -
  667.     mov   al,0ffh                     ;  all data from cpu
  668.     out   dx,al
  669.     xor   ax,ax
  670.     pop   ds                          ; restore data segment
  671.     pop   di                          ; restore registers
  672.     pop   si
  673.     mov   sp,bp                       ; dealloc local variables
  674.     pop   bp
  675.     ret
  676. _x_put_masked_vbm_clipxy  endp
  677.  
  678.  
  679.     end
  680.  
  681.